package com.neu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neu.base.PageBean;
import com.neu.base.Result;
import com.neu.entity.Tenant;
import com.neu.entity.User;
import com.neu.entity.security.LoginUser;
import com.neu.events.UserUpdateEvent;
import com.neu.mapper.UserMapper;
import com.neu.service.TenantService;
import com.neu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>  implements UserService {

    @Autowired
    private  UserMapper userMapper;
    @Autowired
    private TenantService tenantService;
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @Override
    public PageBean<User> pagelist(Integer pageNum, Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDelFlag, "1");// 查询未删除的用户

        //根据当前登录用户的权限查询通知
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<String> permissions = loginUser.getAuthorityStrings();

        if (!permissions.contains("ROLE_super")) {
            queryWrapper.eq(User::getTenantId, loginUser.getTenantId());
        }

        //Page 是 IPage 的具体实现类
        Page<User> userIPage = userMapper.selectPage(page, queryWrapper);
        PageBean<User> pageBean = new PageBean<>(userIPage);
        return pageBean;
    }
    @Override
    public PageBean<User> search(Map map) {
        Integer pageNum = (Integer) map.get("pageNum");
        Integer pageSize = (Integer) map.get("pageSize");

        // 获取嵌套的 search Map
        Map<String, Object> searchMap = (Map<String, Object>) map.get("search");
        //{pageNum=1, pageSize=10, search={username=, phone=, status=1, createTimeList=[2024-10-27T16:00:00.000Z, 2024-11-03T16:00:00.000Z], deptIdList=[1842128938393600002, 1842128590274756609]}}

        // 从 search Map 中获取值
        String username = (String) searchMap.get("username");
        String phone = (String) searchMap.get("phone");
        String status = (String) searchMap.get("status");
        List<String> createTimeList = (List<String>) searchMap.get("createTimeList");
        List<String> tenantIdList = (List<String>) searchMap.get("tenantIdList");

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        //根据当前登录用户的权限查询
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<String> permissions = loginUser.getAuthorityStrings();
        if (!permissions.contains("ROLE_super")) {
            queryWrapper.eq(User::getTenantId, loginUser.getTenantId());
        }

        //把日期字符串转换为日期对象
        LocalDateTime startTime = null;
        LocalDateTime endTime = null;
        if (createTimeList != null && createTimeList.size() == 2) {
            //OffsetDateTime适用于解析带有 "Z" 的日期字符串。
            startTime = OffsetDateTime.parse(createTimeList.get(0), DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime();
            endTime = OffsetDateTime.parse(createTimeList.get(1), DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDateTime();
        }

        Page<User> page = new Page<>(pageNum, pageSize);

        queryWrapper.like(StringUtils.hasText(username), User::getUsername, username)
                .like(StringUtils.hasText(phone), User::getPhone, phone)
                .eq(StringUtils.hasText(status), User::getStatus, status)
                .between(createTimeList != null && createTimeList.size() == 2, User::getCreateTime, startTime, endTime)
                .in(!tenantIdList.isEmpty(),User::getTenantId, tenantIdList);

        Page<User> userIPage = userMapper.selectPage(page, queryWrapper);

        return new PageBean<>(userIPage);
    }


    @Override
    public User updateState(String username, String status) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);

        User user = new User();
        user.setStatus(status);
        user.setUpdateTime(LocalDateTime.now());

        int rows = userMapper.update(user, queryWrapper);

        if (rows > 0) {
            return userMapper.selectOne(queryWrapper);
        } else {
            throw new RuntimeException("更新失败，可能用户不存在");
        }
    }

    @Override
    public List<User> findUserByTenantId(String tenantId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getTenantId, tenantId);
        return userMapper.selectList(queryWrapper);
    }

    @Override
    public List<User> all() {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getDelFlag, "1");// 查询未删除的用户

        //根据当前登录用户的权限查询
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<String> permissions = loginUser.getAuthorityStrings();

        if (!permissions.contains("ROLE_super")) {
            queryWrapper.eq(User::getTenantId, loginUser.getTenantId());
        }
        return this.list(queryWrapper);
    }

    @Override
    public Result updateInfo(User user) {
        String email = user.getEmail();
        String phone = user.getPhone();
        //验证一下邮箱格式
        if(!email.contains("@")){
            return Result.error("邮箱格式错误");
        }
        if(phone.length()!=11){
            return Result.error("手机号格式错误");
        }
        user.setUpdateTime(LocalDateTime.now());
        this.updateById(user);

        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user.getUserId().equals(loginUser.getUserId())) {
            eventPublisher.publishEvent(new UserUpdateEvent(this, user));
        }
        return Result.success("更新成功");
    }

    @Override
    public Result updatePwd(String oldPassword, String newPassword, String confirmPassword) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String rightPassword = loginUser.getPassword();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (!encoder.matches(oldPassword, rightPassword)) {
            return Result.error("原密码错误");
        }
        if (!newPassword.equals(confirmPassword)) {
            return Result.error("两次密码不一致");
        }
        String userId = loginUser.getUserId();
        User user = this.getById(userId);
        user.setPassword(encoder.encode(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        this.updateById(user);
        return Result.success("修改成功");
    }


    private boolean checkUsername(String username) {
        //如果存在返回true
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return this.getOne(queryWrapper) != null;
    }

    private boolean checkEmail(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        return this.getOne(queryWrapper) != null;
    }

    private boolean checkPhone(String phone) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);
        return this.getOne(queryWrapper) != null;
    }

    private boolean checkTenantName(String tenantName) {
        LambdaQueryWrapper<Tenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tenant::getTenantName, tenantName);
        return tenantService.getOne(queryWrapper) != null;
    }

}
